package com.acgist.snail.downloader.ftp;

import java.nio.channels.Channels;

import com.acgist.snail.context.ITaskSession;
import com.acgist.snail.downloader.MonofileDownloader;
import com.acgist.snail.logger.Logger;
import com.acgist.snail.logger.LoggerFactory;
import com.acgist.snail.net.NetException;
import com.acgist.snail.net.ftp.FtpClient;
import com.acgist.snail.utils.FileUtils;
import com.acgist.snail.utils.IoUtils;

/**
 * FTP任务下载器
 * 
 * @author acgist
 */
public final class FtpDownloader extends MonofileDownloader {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(FtpDownloader.class);
	
	/**
	 * FTP客户端
	 */
	private FtpClient client;
	
	/**
	 * @param taskSession 任务信息
	 */
	private FtpDownloader(ITaskSession taskSession) {
		super(taskSession);
	}

	/**
	 * @param taskSession 任务信息
	 * 
	 * @return {@link FtpDownloader}
	 */
	public static final FtpDownloader newInstance(ITaskSession taskSession) {
		return new FtpDownloader(taskSession);
	}

	@Override
	public void release() {
		if(this.client != null) {
			this.client.close();
		}
		IoUtils.close(this.input);
		IoUtils.close(this.output);
		super.release();
	}
	
	@Override
	protected void buildInput() throws NetException {
		// 连接
		this.client = FtpClient.newInstance(this.taskSession.getUrl());
		if(this.client.connect()) {
			// 打开流
			final long downloadSize = FileUtils.fileSize(this.taskSession.getFile());
			this.input = Channels.newChannel(this.client.download(downloadSize));
			// 断点续传
			if(this.client.range()) {
				LOGGER.debug("FTP断点下载：{}", downloadSize);
				this.taskSession.downloadSize(downloadSize);
			} else {
				LOGGER.debug("FTP重新下载：{}", downloadSize);
				this.taskSession.downloadSize(0L);
			}
		} else {
			this.fail("FTP服务器连接失败");
		}
	}
	
}
